const AuthUtil = require('../utils/AuthUtil');
const orderService = require('../service/OrderService');
const OrderHistoryDto = require('../dto/OrderHistoryDto');
const CreateOrderRequest = require('../dto/CreateOrderRequest');
const BusinessExceptionProxy = require('../exception/BusinessExceptionProxy');

// ---------- lambda entry ----------

/**
 * createOrder
 * @param {Object} event
 * @param {Object} context
 * @return {Empty}
 */
async function createOrder(event, context) {
  console.info('create order', event);

  const order = new CreateOrderRequest(event);

  await orderService.createOrder(order);

  return {};
}

/**
 * listOrders
 * @param {Object} event
 * @param {Object} context
 * @return {Object}
 */
async function listOrders(event, context) {
  const validUser = AuthUtil.getUsername(event);
  let { offset, limit } = event.pathParameters;

  let result = await orderService.listMyOrders(validUser, Number(offset), Number(limit));

  console.info('list my order', result);

  return result;
}

/**
 * history
 * @param {Object} event
 * @param {Object} context
 * @return {OrderHistoryDto}
 */
async function history(event, context) {
  const validUser = AuthUtil.getUsername(event);
  let { offset, limit } = event.body;

  let result = await orderService.history(validUser, Number(offset), Number(limit));

  console.info('list my history order', result.length);

  return new OrderHistoryDto(result);
}

/**
 * cancelOrder
 * @param {Object} event
 * @param {Object} context
 * @return {Object}
 */
async function cancelOrder(event, context) {
  console.info('cancel order', event);

  const validUser = AuthUtil.getUsername(event);
  const { id } = event.body;

  await orderService.cancelOrder(validUser, id);

  return { id };
}

/**
 * detail
 * @param {Object} event
 * @param {Object} context
 * @return {Object}
 */
async function detail(event, context) {
  const validUser = AuthUtil.getUsername(event);
  const { id } = event.pathParameters;

  const order = await orderService.getDetail(validUser, id);

  return order;
}

/**
 * @param {Object} event
 * @param {Object} context
 * @return {Promise<void>}
 */
async function getFreezeAmount(event, context) {
  const username = AuthUtil.getUsername(event);
  const { coinTypes } = event.body;

  console.info('get freeze amount:', username, coinTypes);

  if (!(coinTypes instanceof Array)) {
    BusinessExceptionProxy.parameterValueError(['coinTypes']);
  }

  const result = {};
  for (const coinType of coinTypes) {
    result[coinType] = 0;
  }

  const freezeAmounts = await orderService.getFreezeAmount(username, coinTypes);

  for (const freezeAmount of freezeAmounts) {
    result[freezeAmount.coinType] = Number(freezeAmount.amount);
  }

  return result;
}

module.exports = {
  createOrder,
  listOrders,
  history,
  cancelOrder,
  detail,
  getFreezeAmount,
};

// ---------- internal functions ----------
